/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bakenote.ui;

import bakenote.components.RateImageView;
import bakenote.core.GetProcedureException;
import bakenote.core.SaveProcedureException;
import bakenote.core.SaveRecipeException;
import bakenote.data.RecipeList;
import bakenote.data.RecipeSQLiteDB;
import bakenote.core.Recipe;
import bakenote.xml.ProcedureXMLWriter;
import com.sun.org.apache.xpath.internal.operations.Bool;
import org.apache.pivot.beans.BXML;
import org.apache.pivot.beans.BXMLSerializer;
import org.apache.pivot.beans.Bindable;
import org.apache.pivot.collections.Map;
import org.apache.pivot.serialization.SerializationException;
import org.apache.pivot.util.Resources;
import org.apache.pivot.wtk.*;
import org.apache.pivot.wtk.content.ButtonData;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author lello
 */
public class RecipeEditorPane extends TablePane implements Bindable {

    private static Recipe newRecipe = null;
    private static Recipe editedRecipe = null;

    @BXML
    private static PushButton saveAsNewButton = null;
    @BXML
    private static IngredientEditorPane ingredientEditorPane = null;
    @BXML
    private static NoteEditorPane noteEditorPane = null;
    @BXML
    private static ProcedureEditorPane procedureEditorPane = null;
    @BXML
    private static ButtonData editorTabTitle = null;
    @BXML
    private static TextInput recipeTitle = null;
    @BXML
    private static TextInput recipeAuthor = null;
    @BXML
    private static TextInput recipeSource = null;
    @BXML
    private static TextInput recipeKind = null;
    @BXML
    private static TextInput recipeTag = null;
    @BXML
    private static RateImageView rateImageView = null;

    private static BXMLSerializer bxmlSerializer = null;

    public RecipeEditorPane() {
        // No-op
    }

    public static RecipeEditorPane newInstance() {
        bxmlSerializer = new BXMLSerializer();
        RecipeEditorPane r = null;
        try {
            r = (RecipeEditorPane) bxmlSerializer.readObject(RecipeEditorPane.class, "recipe_editor_pane.bxml");
        } catch (IOException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } catch (SerializationException e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return r;
    }

    public void editInfo(Recipe r) {

        //System.out.println("editing recipe "+r.getName());
        // Cache recipe
        editedRecipe = r;

        recipeTitle.setText(r.getName());
        if (editedRecipe.getAuthor() != null) {
            recipeAuthor.setText(editedRecipe.getAuthor());
        }
        if (editedRecipe.getSource() != null) {
            recipeSource.setText(editedRecipe.getSource());
        }
        if (editedRecipe.getType() != null) {
            recipeKind.setText(editedRecipe.getType());
        }
        if (editedRecipe.getTag() != null) {
            recipeTag.setText(editedRecipe.getTag());
        }

        rateImageView.setRate(r.getRating());
    }

    public PushButton getButton(String buttonName) {
        return (PushButton) bxmlSerializer.getNamespace().get(buttonName);
    }

    public void initialize(Map<String, Object> map, URL url, Resources rsrcs) {
        editedRecipe = null;
        newRecipe = null;

        rateImageView.setRate(0);

        rateImageView.getComponentMouseListeners().add(new ComponentMouseListener() {

            @Override
            public boolean mouseMove(Component cmpnt, int x, int y) {
                //System.out.println("coord x y :" + x + " " + y);
                rateImageView.chooseRate(x, y);
                return true;
            }

            public void mouseOver(Component cmpnt) {
                //throw new UnsupportedOperationException("Not supported yet.");
            }

            public void mouseOut(Component cmpnt) {
                rateImageView.setChosenRate();
            }
        });

        rateImageView.getComponentMouseButtonListeners().add(new ComponentMouseButtonListener.Adapter() {
            @Override
            public boolean mouseClick(Component cmpnt, Mouse.Button button, int x, int y, int count) {
                rateImageView.setRate(x, y);
                return true;
            }
        });
    }

    public void disableSaveAsNewButton() {
        saveAsNewButton.setEnabled(false);
    }

    private boolean nameProvided() {
        return !recipeTitle.getText().trim().isEmpty();
    }

    public Recipe getNewRecipe() {
        return newRecipe;
    }

    public Recipe getEditedRecipe() {
        if (editedRecipe == null) {
            System.out.println("error null editedRecipe");
        }
        return editedRecipe;
    }

    public void setTitle(String s) {
        editorTabTitle.setText(s);
    }

    /**
     * This is called only when an existing recipe is edited
     *
     * @param r
     */
    public void editRecipe(Recipe r) {
        // no need for local copy (java passes by value
        //Recipe editedRecipeCopy = new Recipe(r);i
        // Set the currently edited recipe
        editedRecipe = r;
        // display all recipe information to be edited
        this.editInfo(editedRecipe);
        ingredientEditorPane.editIngredients(editedRecipe);
        procedureEditorPane.editProcedure(editedRecipe);
        noteEditorPane.editNote(editedRecipe);
        editorTabTitle.setText(editedRecipe.getName());

    }


    private Recipe getRecipe(boolean asNew) throws GetProcedureException {

        // Create new recipe or edit an existing one
        if (editedRecipe == null || asNew) {
            newRecipe = new Recipe();
            // Create a UUID for the recipe
            newRecipe.createUUID();
        } else {
            // editing an existing recipe
            newRecipe = editedRecipe;
        }

        // Add the formulas to the recipe
        newRecipe.setFormulaList(ingredientEditorPane.getRecipeIngredients(asNew));
        // Set Title, Author, Tags, Source and Type
        newRecipe.setName(recipeTitle.getText().trim());
        newRecipe.setAuthor(recipeAuthor.getText().trim());
        newRecipe.setSource(recipeSource.getText().trim());
        newRecipe.setTag(recipeTag.getText().trim());
        newRecipe.setType(recipeKind.getText().trim());
        newRecipe.setRating(rateImageView.getRate());
        // set recipe procedure
        newRecipe.setProcedure(procedureEditorPane.getProcedure());
        newRecipe.setNote(noteEditorPane.getNote());

        return newRecipe;

    }

    public boolean saveRecipe(boolean asNew) throws SaveRecipeException, GetProcedureException {

        boolean result = false;

        newRecipe = getRecipe(asNew);

        // now we can add the recipe to the recipeList
        RecipeList.add(newRecipe);

        // at this point we can save the recipe into the database
        if (asNew || (editedRecipe == null)) {
            // We are creating a new recipe
            //Recipe r = ingredientEditorPane.getRecipeIngredients(asNew);
            if (nameProvided()) {
                //System.out.println("saving recipe as new");
                try {
                    RecipeSQLiteDB.saveRecipe(newRecipe);
                } catch (SQLException ex) {
                    Logger.getLogger(BakeNoteWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
            } else {
                throw new SaveRecipeException("Please insert a title.");
            }
        } else {
            // We are editing an existing recipe
            if (editedRecipe != null) {
                if (nameProvided()) {
                    // editedRecipe, which might be displayed in a tab, is updated.
                    try {
                        RecipeSQLiteDB.updateRecipe(newRecipe);
                    } catch (SQLException ex) {
                        Logger.getLogger(BakeNoteWindow.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } else {
                    throw new SaveRecipeException("Please insert a title.");
                }
            }
        }

        try {
            if (newRecipe.getProcedure() != null) {
                System.out.println("saving procedure");
                RecipeSQLiteDB.saveProcedure(newRecipe.getUUID(), newRecipe.getProcedure().getXML());
            }
            if (!newRecipe.getNote().isEmpty()) {
                System.out.println("note " + newRecipe.getNote());
                RecipeSQLiteDB.saveNote(newRecipe.getUUID(), newRecipe.getNote());
            }
            result = true;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return result;
    }


}
